#pragma once
#include "actor.h"
#include <string>
#include <map>
#include <functional>
#include <regex>

#define State_OK                0
#define State_Sys_Error         1
#define State_Connection_Faile  2
#define State_Connection_Close  3
#define State_Date_Error        4
#define State_Ssl_No_Support    5

using HttpHeader = std::map<std::string, std::string>;

class HttpRequest {
public:
    std::string method;
    std::string uri;
    std::string query;
    std::string version;
    std::string content;
    HttpHeader  header;
};

class HttpResponse {
public:
    std::string version;
    int         state_code;
    std::string state;
    std::string content;
    HttpHeader  header;
};

class HttpTask;
typedef void(*HTTP_CALLBACK)(HttpTask*, BaseWorker*, HttpResponse*, int);
using HTTP_RESFUNC = std::function<void(HttpResponse&, int)>;

class HttpTask {
public:
    HttpRequest*    request;
    HttpResponse*   response;
    HTTP_CALLBACK   call;
    BaseWorker*     worker;
    union{
        void* user_data;
        long long user_number;
    };
};

class HttpClientDriver :public BaseWorker {
public:
    void ConnectionMade(HSOCKET hsock, PROTOCOL protocol);
    void ConnectionFailed(HSOCKET hsock, int err);
    void ConnectionClosed(HSOCKET hsock, int err);
    void ConnectionRecved(HSOCKET hsock, const char* data, int len);
 
    HttpTask* request(BaseWorker* worker, const char* method, const char* url, HttpHeader* header, const char* content, HTTP_CALLBACK callback);
    HttpTask* request(BaseWorker* worker, const char* method, const char* url, HttpHeader* header, const char* content, std::function<void(HttpResponse&, int state)> func);
};

extern thread_local HttpClientDriver* HttpClient;

#ifdef __cplusplus
extern "C"
{
#endif

int http_client_driver_regist();
int http_request(BaseWorker* worker, const char* method, const char* url, HttpHeader* header, const char* content, HTTP_CALLBACK callback);

#ifdef __cplusplus
}
#endif